package cn.exrick.xboot.base.serviceimpl

import cn.exrick.xboot.base.entity.*
import cn.exrick.xboot.base.mapper.EnterpriseUserMapper
import cn.exrick.xboot.base.service.*
import cn.exrick.xboot.base.vo.EnterpriseUserDetailVo
import cn.exrick.xboot.base.vo.EnterpriseUserListVo
import cn.exrick.xboot.base.vo.EnterpriseUserStatistics
import cn.exrick.xboot.base.vo.MyCompanyInfoVo
import cn.exrick.xboot.core.common.constant.CommonConstant
import cn.exrick.xboot.core.common.utils.PageUtil
import cn.exrick.xboot.core.common.utils.ResultUtil
import cn.exrick.xboot.core.common.utils.ResultUtil.success
import cn.exrick.xboot.core.common.utils.SecurityUtil
import cn.exrick.xboot.core.common.utils.ToolUtil
import cn.exrick.xboot.core.common.vo.Result
import cn.exrick.xboot.core.entity.User
import cn.exrick.xboot.core.entity.UserRole
import cn.exrick.xboot.core.service.RoleService
import cn.exrick.xboot.core.service.UserService
import cn.exrick.xboot.core.service.mybatis.IUserRoleService
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.google.common.collect.Maps
import lombok.SneakyThrows
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.integration.redis.util.RedisUtils
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.math.BigDecimal
import javax.annotation.Resource

/**
 * 企业用户接口实现
 * @author Fei
 */
@Slf4j
@Service
@Transactional
open class IEnterpriseUserServiceImpl : ServiceImpl<EnterpriseUserMapper?, EnterpriseUser?>(), IEnterpriseUserService {


    @Autowired
    private lateinit var areaService: IAreaService

    @Autowired
    private lateinit var iEnterpriseEmployeeService: IEnterpriseEmployeeService

    @Autowired
    private lateinit var iBusinessService: IBusinessService

    @Autowired
    private lateinit var iEnterpriseUserCheckService: IEnterpriseUserCheckService

    @Autowired
    private lateinit var iEnterpriseUserStatusService: IEnterpriseUserStatusService

    @Autowired
    private lateinit var redisTemplate: StringRedisTemplate

    @Autowired
    private lateinit var iEnterpriseCommonParamService: IEnterpriseCommonParamService

    @Autowired
    private lateinit var iEmployeeExamStatusService: IEmployeeExamStatusService

    @Autowired
    private lateinit var userService: UserService

    @Autowired
    private lateinit var iUserRoleService: IUserRoleService

    @Autowired
    private lateinit var roleService: RoleService

    @Autowired
    private lateinit var securityUtil: SecurityUtil

    @Autowired
    private lateinit var iAreaService: IAreaService


    override fun insertCompanyInfo(enterpriseUser: EnterpriseUser, code: String?, checkUserId: String): Result<Any?>? {

       return try {

          /* //短信验证码
           val codeGet = redisTemplate.opsForValue().get(CommonConstant.PRE_SMS.plus(enterpriseUser.registerUserPhone))

           codeGet?.let {

               if (it != code) return ResultUtil.error(202, "短信验证码不一致！")

               //1.企业信息
               save(enterpriseUser.apply { password = BCryptPasswordEncoder().encode(password) })

               //2. 企业审核信息
               iEnterpriseUserCheckService.save(EnterpriseUserCheck().apply {

                   enterpriseUserId = enterpriseUser.id
                   areaId = enterpriseUser.areaId
                   checkUser = checkUserId
               })

               //3.企业状态信息
               iEnterpriseUserStatusService.save(EnterpriseUserStatus().apply {

                   enterpriseUserId = enterpriseUser.id
               })
               return success("提交成功")
           } ?: ResultUtil.error(203, "验证码失效！")*/
           //1.企业信息
           save(enterpriseUser.apply { password = BCryptPasswordEncoder().encode(password) })

           //2. 企业审核信息
           iEnterpriseUserCheckService.save(EnterpriseUserCheck().apply {

               enterpriseUserId = enterpriseUser.id
               areaId = enterpriseUser.areaId
               checkUser = checkUserId
           })

           //3.企业状态信息
           iEnterpriseUserStatusService.save(EnterpriseUserStatus().apply {

               enterpriseUserId = enterpriseUser.id
           })
           return success("提交成功")

       } catch (e : Exception) {

           ResultUtil.error(e.message)
       }
    }

    override fun getMyCompanyInfo(): Result<MyCompanyInfoVo>? {

        return getOne(KtQueryWrapper(EnterpriseUser::class.java).eq(EnterpriseUser::createBy, securityUtil.currUser.id)
                .orderByDesc(EnterpriseUser::createTime).last("limit 1"))?.run {

            ResultUtil.data(MyCompanyInfoVo().apply {

                ToolUtil.copyProperties(this@run, this)
                businessName = iBusinessService.getBusinessNameById(businessId)
                address = iAreaService.getAreaFullNameByAreaId(areaId)?.plus("/").plus(registerAddress)
                licensePics = licensePic?.split(",")
                identityCards = identityCard?.split(",")

                //审核信息
                iEnterpriseUserCheckService.getOne(KtQueryWrapper(EnterpriseUserCheck::class.java)
                        .eq(EnterpriseUserCheck::enterpriseUserId, id).orderByDesc(EnterpriseUserCheck::createTime)
                        .last("limit 1"))?.let {

                    ToolUtil.copyProperties(it, this)
                    checkUser = userService.get(it.checkUser)?.nickname
                    checkStatus = when (it.checkStatus) {
                        1 -> {
                            "待审核"
                        }
                        2 -> {
                            "审核通过"
                        }
                        else -> {
                            "审核失败"
                        }
                    }

                }
            })
        } ?: ResultUtil.error(201, "暂无信息")

    }

    override fun getEnterpriseUserVo(id: String): EnterpriseUserListVo? {

       return getById(id)?.run {

            EnterpriseUserListVo().apply {

                businessName = iBusinessService.getBusinessNameById(businessId)
                companyAddress = areaService.getAreaFullNameByAreaId(areaId)?.plus(registerAddress)
                managementForms = iEnterpriseUserStatusService.getOne(KtQueryWrapper(EnterpriseUserStatus::class.java).eq(EnterpriseUserStatus::enterpriseUserId, id))?.managementForms
                headcount = when (iEnterpriseEmployeeService.getEnterpriseEmployeeTotalCount(id)) {

                    in 0..49 -> {
                        "0-49人"
                    }
                    in 50..99 -> {
                        "50-99人"
                    }
                    in 100..499 -> {
                        "100-499人"
                    }
                    in 500..999 -> {
                        "500-999人"
                    }
                    in 1000..4999 -> {
                        "1000-4999人"
                    }
                    else -> {
                        "大于5000人"
                    }
                }
                ToolUtil.copyProperties(this@run, this)
            }
        }
    }

    override fun getEnterpriseIdByAreaId(areaId: String): MutableList<String>? {

       return ToolUtil.setListToNul(list(KtQueryWrapper(EnterpriseUser::class.java).eq(EnterpriseUser::areaId, areaId).orderByDesc(EnterpriseUser::createTime))
                .filter { iEnterpriseUserStatusService.getOne(KtQueryWrapper(EnterpriseUserStatus::class.java).eq(EnterpriseUserStatus::enterpriseUserId, it!!.id))
                        ?.managementForms == CommonConstant.SUBSIST })?.run {
            mapNotNull { it!!.id }.toMutableList()
        }
    }

    override fun getEnterpriseDetail(id: String): Result<EnterpriseUserDetailVo?>? {

        return getById(id)?.run {

            ResultUtil.data(EnterpriseUserDetailVo().apply {

                enterpriseUserListVo = getEnterpriseUserVo(id)
                enterpriseUserStatistics = getEnterpriseStatistics(id)
                managementForms = iEnterpriseUserStatusService.getOne(KtQueryWrapper(EnterpriseUserStatus::class.java).eq(EnterpriseUserStatus::enterpriseUserId, id))?.managementForms
                overview = iEnterpriseCommonParamService.getOne(KtQueryWrapper(EnterpriseCommonParam::class.java).eq(EnterpriseCommonParam::enterpriseUserId, id)
                                .orderByDesc(EnterpriseCommonParam::createTime).last("limit 1"))?.overview
                ToolUtil.copyProperties(this@run, this)
            }, "获取详情成功")
        } ?: ResultUtil.error(201, "不存在该企业")
    }

    override fun getEnterpriseStatistics(id: String): EnterpriseUserStatistics? {

        return EnterpriseUserStatistics().apply {

           ToolUtil.setListToNul(iEnterpriseEmployeeService.list(KtQueryWrapper(EnterpriseEmployee::class.java).eq(EnterpriseEmployee::enterpriseId, id)))?.run {

               employeeTotalNum = size
               trainingTotalNum = filter { ToolUtil.isNotEmpty(iEmployeeExamStatusService.getOne(KtQueryWrapper(EmployeeExamStatus::class.java)
                       .eq(EmployeeExamStatus::createBy, it?.userId))) }.count()
               notTrainingTotalNum = employeeTotalNum!! - trainingTotalNum!!
               studyTotalNum = filter { ToolUtil.isNotEmpty(iEmployeeExamStatusService.getOne(KtQueryWrapper(EmployeeExamStatus::class.java)
                       .eq(EmployeeExamStatus::createBy, it?.userId)
                       .between(EmployeeExamStatus::completeProcess, 0, 5))) }.count()
               passTotalNum = filter { ToolUtil.isNotEmpty(iEmployeeExamStatusService.getOne(KtQueryWrapper(EmployeeExamStatus::class.java)
                       .eq(EmployeeExamStatus::createBy, it?.userId)
                       .eq(EmployeeExamStatus::completeTraining, true))) }.count()
               notPassTotalNum = employeeTotalNum!! - passTotalNum!!
               trainingSchedule = BigDecimal(passTotalNum!!).divide(BigDecimal(employeeTotalNum!!)).toDouble()
               passSchedule = trainingSchedule
           }
        }
    }


    override fun getEnterpriseNameById(id: String?): String? {

        return getById(id)?.companyName
    }

    override fun getEnterpriseIdByEmployeeUserId(employeeUserId: String?): String? {

        return iEnterpriseEmployeeService.getOne(KtQueryWrapper(EnterpriseEmployee::class.java).eq(EnterpriseEmployee::userId, employeeUserId))?.enterpriseId
    }

    override fun getEnterpriseIdByUserId(): String {

        return getOne(KtQueryWrapper(EnterpriseUser::class.java).eq(EnterpriseUser::createBy, securityUtil.currUser.id))?.id!!
    }

}
